package com.ktmall.controller;

import com.ktmall.utils.*;
import com.ktmall.pojo.Order;
import com.ktmall.pojo.WxUser;
import com.ktmall.service.OrderService;
import com.ktmall.service.WxUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Api(tags = "微信支付相关接口")
@RestController
@RequestMapping("/uni/pay")
public class PayController {
    private final static String appId ;
    private final static String secret ;
    private final static String accessTokenhttps ;
    private final static String webAccessTokenhttps ;

    private final static String mchId;
    private final static String mchKey;
    private final static String tradeType;
    private final static String notifyUrl;
    private final static String uniformorder;
    private final static String orderquery;

    static String configFile = "application.properties";//微信配制文件路径

    static {
        Properties properties = new Properties();
        try {
            properties.load(PhoneLoginController.class.getClassLoader().getResourceAsStream(configFile));
            appId=properties.getProperty("wx.appId");
            accessTokenhttps=properties.getProperty("wx.accessTokenhttps");
            secret = properties.getProperty("wx.secret");
            webAccessTokenhttps = properties.getProperty("wx.webAccessTokenhttps");
            mchId = properties.getProperty("wx.mchId");
            mchKey = properties.getProperty("wx.mchKey");
            tradeType = properties.getProperty("wx.tradeType");
            notifyUrl = properties.getProperty("wx.notifyUrl");
            uniformorder = properties.getProperty("wx.uniformorder");
            orderquery = properties.getProperty("wx.orderquery");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Autowired
    private WxUserService wxUserService;
    @Autowired
    private OrderService orderService;

    private RespMsg respMsg;

    @ApiOperation("微信支付")
    @GetMapping("/prepay")
    public RespMsg prepay(Integer userId, Integer orderId, HttpServletRequest request){
        WxUser loginUser = wxUserService.findById(userId);
        Order orderInfo = orderService.findById(orderId);

        if(orderInfo == null){
            return respMsg.fail("订单已取消");
        }

        if(orderInfo.getOrderState() != 1){
            return respMsg.fail("订单已支付，请不要重复操作");
        }

        String nonceStr = CharUtils.getRandomString(32);
        Map<String,String> resultObj = new TreeMap<>();

        try {
            Map<String,String> parame = new TreeMap<>();
            parame.put("appid",appId);
            System.out.println("appId:" + appId);
            parame.put("mch_id",mchId);
            System.out.println("mchId:" + mchId);
            String randomStr = CharUtils.getRandomString(18).toUpperCase();
            parame.put("nonce_str",randomStr);
            System.out.println("nonce_str:" + randomStr);
            parame.put("out_trade_no",orderInfo.getOrderSn());
            System.out.println("out_trade_no:" + orderInfo.getOrderSn());
            Map orderGoodsParam = new HashMap();
            orderGoodsParam.put("order_id",orderInfo.getId());
            parame.put("body","支付");
            parame.put("total_fee",String.valueOf(1));
            System.out.println("total_fee:" + String.valueOf(orderInfo.getActualPrice().multiply(new BigDecimal(100)).setScale(0,BigDecimal.ROUND_HALF_UP)));
            parame.put("notify_url",notifyUrl);
            System.out.println("notify_url:" + notifyUrl);
            parame.put("trade_type",tradeType);
            System.out.println("trade_type:" + tradeType);
            parame.put("spbill_create_ip",getClientIp(request));
            System.out.println("spbill_create_ip:" + getClientIp(request));
            parame.put("openid",loginUser.getOpenId());
            System.out.println("openid:" + loginUser.getOpenId());
            String sign = WXPayUtil.generateSignature(parame,mchKey);
            parame.put("sign",sign);
            System.out.println("sign:" + sign);
            String xml = WXPayUtil.mapToXml(parame);
            Map<String,Object> resultUn = XmlUtil.xmlStrToMap(WechatUtil.requestOnce(uniformorder,xml));
            System.out.println("微信统一下单返回XML：" + resultUn);
            String return_code = MapUtils.getString("return_code",resultUn);
            String return_msg = MapUtils.getString("return_msg",resultUn);

            if(return_code.equalsIgnoreCase("FAIL")){
                return RespMsg.fail("支付失败，失败信息是" + return_msg);
            }else if(return_code.equalsIgnoreCase("SUCCESS")){
                String result_code = MapUtils.getString("result_code",resultUn);
                String err_code_des = MapUtils.getString("err_code_des",resultUn);
                if(result_code.equalsIgnoreCase("FAIL")){
                    return RespMsg.fail("支付失败，" + err_code_des);
                }else if(result_code.equalsIgnoreCase("SUCCESS")){
                    String prepay_id = MapUtils.getString("prepay_id",resultUn);
                    resultObj.put("appId",appId);
                    resultObj.put("timeStamp", DateUtils.timeToStr(System.currentTimeMillis(),DateUtils.DATE_TIME_PATTERN));
                    resultObj.put("nonceStr",nonceStr);
                    resultObj.put("package","prepay_id=" + prepay_id);
                    resultObj.put("signType","MD5");


                    String packageSign = WXPayUtil.generateSignature(resultObj,mchKey);
                    resultObj.put("paySign",packageSign);
                    System.out.println("====================支付签名paySign为：" + packageSign);


                    orderInfo.setOrderState(2);
                    orderInfo.setPayTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                    orderService.updatePayStatus(orderInfo);

                    return respMsg.success("微信统一订单下单成功",resultObj);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            return respMsg.fail("下单失败，error=" + e.getMessage());
        }
        return respMsg;
    }

    private String getClientIp(HttpServletRequest request){
        String xff = request.getHeader("X-Real-IP");
        if(xff != null){
            return xff;
        }
        xff = request.getHeader("x-forwarded-for");
        if(xff == null){
            return "8.8.8.8";
        }
        return xff;
    }

}
